package  control
{

	import control.controlBoxParts.ControlPoint;
	import control.controlBoxParts.IBoundsControlAware;
	import control.controlBoxParts.IEidtableComponent;
	import control.controlBoxParts.PosConst;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	import mx.core.UIComponent;
	
    /**控制点的大小，宽和高一样，为正方形*/
    [Style(name="controlRecWidth", type="int", inherit="yes")]
    
     /**画控制点,控制线的size*/
    [Style(name="controlLineThickness", type="int", inherit="yes")]
    
      /**画控制点,控制线的size*/
    [Style(name="controlColor", type="int", inherit="no")]
    
     /**控制类型*/
    [Style(name="controlType", type="String", enumeration="size, transform, none", inherit="yes")]
    
	public class ControlBox extends UIComponent 
	{	
		private var _showControl: Boolean;
		
		private var _selected: Boolean;
		
		private var controlPoint:ControlPoint;
		
		private var size:Rectangle;
	
	    private var canSizeChange:Boolean;
	    
	    private var enableMove:Boolean;
		
		//控制点在stage上刚开始的位置
		private var op: Point;
		
		/**刚开始该box在parent的位�*/
		private var boxPointOnParent: Point;
		
		private var moveDir: String;
		
		private var mouseDeltaX: Number;
		
		private var mouseDeltaY:Number;
		
		//保存上次被其他操作改变过的b
		
		private var savedB:Number = Number.MIN_VALUE;
		
		private var savedC:Number = Number.MIN_VALUE;
		
		private var tempPoint:Point = new Point(Number.MIN_VALUE, Number.MIN_VALUE);
		
		//是否开始操作，跟踪整个操作的生命周期 
		private var _started: Boolean;
	
		//以下是各个控制点
		private var tlPoint:ControlPoint;
		
		private var tmPoint:ControlPoint;
		
		private var trPoint:ControlPoint;
		
		private var mlPoint:ControlPoint;
		
		private var mrPoint:ControlPoint;
		
		private var llPoint:ControlPoint;
		
		private var lmPoint:ControlPoint;
		
		private var lrPoint:ControlPoint;
		
		/**
		 * 控制的组件,1对1的关系
		 */
		private var _controlWidget:DisplayObject;
		
		private var _liveSize:Boolean;
		
		/**用于显示拖动时的长宽高*/
		private var displayTextField:TextField;
		
		/**一像素代表多少米*/
		private var _unit:Number  =  5 / 60;
		
		private var _inResizing:Boolean;
		
		public function ControlBox()
		{
			super();
			op = new Point();
			boxPointOnParent = new Point();
			this.doubleClickEnabled = true;
			if(!getStyle("controlRecWidth"))
			{
				this.setStyle("controlRecWidth", 4);
			}
			if(!getStyle("controlLineThickness"))
			{
				this.setStyle("controlLineThickness", 1);
			}
			if(!getStyle("controlColor"))
			{
				this.setStyle("controlColor", 0x0000ff);
			}
			//this.setStyle("borderSkin", ControlSkin);
			this.addEventListener(MouseEvent.MOUSE_DOWN, onMouse);
			this.addEventListener(MouseEvent.CLICK, onMouse);	
			this.addEventListener(Event.ADDED_TO_STAGE, getLoacionOnParent);
		}
		
		
		protected override  function createChildren():void
		{
			super.createChildren();
			if(!displayTextField)
			{
				displayTextField = new TextField();
				displayTextField.defaultTextFormat = new TextFormat("宋体", 10);
				displayTextField.autoSize = TextFieldAutoSize.LEFT;
				displayTextField.visible = false;
				this.addChild(displayTextField);
			}
			if(!tlPoint)
			{
				 tlPoint = new ControlPoint(PosConst.TOP_LEFT, this);
				 this.addChild(tlPoint);
			
			     tmPoint= new ControlPoint(PosConst.TOP_MIDDLE, this);
			     this.addChild(tmPoint);
			
			     trPoint= new ControlPoint(PosConst.TOP_RIGHT, this);
			     this.addChild(trPoint);
			
		 	     mlPoint= new ControlPoint(PosConst.MIDDLE_LEFT, this);
		 	     this.addChild(mlPoint);
			
			     mrPoint= new ControlPoint(PosConst.MIDDLE_RIGHT, this);
			     this.addChild(mrPoint);
			
				 llPoint= new ControlPoint(PosConst.LOW_LEFT, this);
				 this.addChild(llPoint);
			
			     lmPoint= new ControlPoint(PosConst.LOW_MIDDLE, this);
			     this.addChild(lmPoint);
			
		         lrPoint= new ControlPoint(PosConst.LOW_RIGHT, this);
		         this.addChild(lrPoint);
		         setControlPointsVisible(false);
		         drawLine(false);
			}
		}
	    
	     public override  function set focusPane(o:Sprite):void
	     {
	     	
	     }
	     
	       override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
	    {
	        super.updateDisplayList(unscaledWidth, unscaledHeight);
	        layoutChrome(unscaledWidth, unscaledHeight);
	        //this.scrollRect = new Rectangle(0, 0, unscaledWidth, unscaledHeight);
	    }
	    
	     protected  function layoutChrome(unscaledWidth:Number, 
	          unscaledHeight:Number):void
        {
	        if(tlPoint && controlWidget )
			{
				 var width:Number = unscaledWidth;
				 var height:Number = unscaledHeight;
				 var p:Point = new Point(0, 0);
				 var w: int =  this.getStyle("controlRecWidth");
				 //controlWidget
				 p = this.getcontrolWidgetLocationOnBox(p);
				 tlPoint.x =  p.x - w / 2;
				 tlPoint.y =  p.y - w / 2;
			
			     p.x = width / 2;
			     p.y = 0;
			     p = this.getcontrolWidgetLocationOnBox(p);
			     tmPoint.x = p.x  - w / 2;
			     tmPoint.y = p.y - w / 2;
			
				 p.x = width;
			     p.y = 0;
			     p = this.getcontrolWidgetLocationOnBox(p);
			     trPoint.x = p.x - w / 2;
			     trPoint.y = p.y - w / 2;
			
			     p.x = 0;
			     p.y = height / 2;
			     p = this.getcontrolWidgetLocationOnBox(p);
		 	     mlPoint.x = p.x - w / 2;
				 mlPoint.y = p.y - w / 2;
			
			     p.x = width;
			     p.y = height / 2;
			     p = this.getcontrolWidgetLocationOnBox(p);
			     mrPoint.x =  p.x - w / 2;
				 mrPoint.y =  p.y - w / 2;
				 
				 p.x = 0;
			     p.y = height;
			     p = this.getcontrolWidgetLocationOnBox(p);
				 llPoint.x = p.x - w / 2;
				 llPoint.y = p.y - w / 2;
			

                 p.x = width / 2;
			     p.y = height;
			     p = this.getcontrolWidgetLocationOnBox(p);
			     lmPoint.x = p.x - w / 2;
				 lmPoint.y =  p.y - w / 2;
			       
			     p.x = width;
			     p.y = height;
			     p = this.getcontrolWidgetLocationOnBox(p);
		         lrPoint.x = p.x - w / 2;
				 lrPoint.y =  p.y - w / 2; 	
				 
				 displayTextField.text = getAreaSize();
				 displayTextField.x = lrPoint.x - displayTextField.width - 6;
				 displayTextField.y =  lrPoint.y - displayTextField.textHeight - 8;
				 if(_started)
				 {
				 	 drawLine(true);		
				 }		
			}
	    }
	    
	    private function getAreaSize():String
	    {
	    	var xDelta:Number = (lrPoint.x - tlPoint.x) * unit;
	    	var YDelta:Number = (lrPoint.y - tlPoint.y) * unit;
	    	return "长: " + Math.round(xDelta) + "米, 宽: " + Math.round(YDelta) + "米";
	    }
	    
	    private function drawLine(paint: Boolean):void
	    {
	        this.graphics.clear();
	        if(paint)
	        {
	        	 var focusColor:Number = getStyle("controlColor");
	             var thinkness: int = getStyle("controlLineThickness");
			     graphics.lineStyle(thinkness, focusColor); 
	        	 var w: int =  this.getStyle("controlRecWidth");
			     graphics.moveTo(tlPoint.x + w / 2, tlPoint.y + w / 2);
			     graphics.lineTo(trPoint.x + w / 2, trPoint.y + w / 2);
			     graphics.lineTo(lrPoint.x + w / 2, lrPoint.y + w / 2);	    
			     graphics.lineTo(llPoint.x + w / 2, llPoint.y + w / 2);    
			     graphics.lineTo(tlPoint.x + w / 2, tlPoint.y + w / 2);    
	        }	
	    }
	    
	    private function getcontrolWidgetLocationOnBox(p: Point):Point
	    {
	    	return p;
	    }
	    
	    private function getInitLocation(dir:int):Point
	    {
    	 	 var w: int =  this.getStyle("controlRecWidth");
			 var width:Number = controlWidget.width;
			 var height:Number = controlWidget.height;
			 var p:Point = new Point(0, 0);
			 if(dir == PosConst.TOP_LEFT)
			 {
			 	 p.x =  - w;
			     p.y =  - w;
			 }
			 else if(dir == PosConst.TOP_MIDDLE)
			 {
			 	 p.x = width / 2 - w / 2;
		         p.y = - w;
			 }
			 else if(dir == PosConst.TOP_RIGHT)
			 {
			 	 p.x = width;
		         p.y = - w;
			 }
			 else if(dir == PosConst.MIDDLE_LEFT)
			 {
			 	 p.x = - w;
		         p.y = height / 2 - w / 2;
			 }
			 else if(dir == PosConst.MIDDLE_RIGHT)
			 {
			 	 p.x = width;
		         p.y = height / 2 - w / 2;
			 }
			 else if(dir == PosConst.LOW_LEFT)
			 {
			 	 p.x = - w;;
		         p.y = height;
			 }
			  else if(dir == PosConst.LOW_MIDDLE)
			 {
			 	 p.x = width / 2 - w / 2;
		         p.y = height;
			 }
			  else if(dir == PosConst.LOW_RIGHT)
			 {
			 	 p.x = width;
		         p.y = height;
			 }
			 return p;			
	    }
	    
	    public override  function styleChanged(styleProp:String):void
	    {
	    	super.styleChanged(styleProp);
	    	if(styleProp == "controlColor")
	    	{
	    		invalidateDisplayList();
	    	}
	    	if(styleProp == "controlRecWidth")
	    	{
	    		invalidateSize();
	    		invalidateDisplayList();
	    	}
	    	else if(styleProp == "controlType")
	    	{
	    		this.savedB = Number.MIN_VALUE;
	    		this.savedC =  Number.MIN_VALUE;
	    		tempPoint.x = Number.MIN_VALUE;
	    		tempPoint.y = Number.MIN_VALUE;
	    	}
	    }
		
		/**
		 * 设置该box是否被选择，同时更新控制框的显�?
		 */			
		public function set selected(selected: Boolean):void
		{
			if(this._selected != selected)
			{
				this._selected = selected;
				showControl = selected;
				if(this._selected)
				{
					this.started = true;
					this.parent.addEventListener(MouseEvent.MOUSE_DOWN, operationEnd);
				}
			}
		}
		
		public function set started(value: Boolean):void
		{
			if(this._started != value)
			{
			   	this._started = value;
			   	this.drawLine(_started);
			}
			if(!value)
			{
				this.setControlPointsVisible(false);
				this.selected = false;
			    if(controlWidget is IEidtableComponent  && IEidtableComponent(controlWidget).isInEdit())
			    {
					IEidtableComponent(controlWidget).stopEdit();
					showControl = false;
				}
			}
		}
		
		public function set showControl(show: Boolean):void
		{
			 if(this._showControl != show)
			 {
			 	 this._showControl = show;
			 	 setControlPointsVisible(_showControl);
			 	 super.notifyStyleChangeInChildren("showControl", true);
			 }
		}
		
		public function get showControl():Boolean
		{
			return this._showControl;
		}
		
		
		private function onMouse(event: MouseEvent):void
		{
			var type: String = event.type;
			trace(type);
			switch(type)
			{
				case MouseEvent.MOUSE_DOWN:
				    onMouseDown(event);
				    break;
			    case MouseEvent.MOUSE_UP:
			        onMouseUp(event);
				    break;
			    case MouseEvent.CLICK:
			        onClick(event);
				    break;
				
			}
		}
		
		/**
		 * 选中该组�?如果子组件处于编辑状态，则停止编�?
		 */
		private function onMouseDown(event: MouseEvent):void
		{
			var target:Object = event.target;
			trace(target);
			if(!this._selected)
			{
				if(controlWidget is IEidtableComponent && !IEidtableComponent(controlWidget).isInEdit())
				{
					this.selected = true;
				}
				if(target == this || target.parent == this)
				{
					this.selected = true;
					if(controlWidget is IEidtableComponent  && IEidtableComponent(controlWidget).isInEdit())
					{
						IEidtableComponent(controlWidget).stopEdit();
						this.setFocus();
					}
				}
				return;
			}
			//当选择的时候，得到当前的控制点，准备根据用户的操作来控制组件的尺寸或者transform
			if(target is ControlPoint)
			{
				controlPoint = ControlPoint(target);
				canSizeChange = getStyle("controlType") == "size";			
				prepareControl(false);	
				op.x = this.x;
				op.y = this.y;
				op = this.localToGlobal(op);
				op.x += controlPoint.x;
				op.y += controlPoint.y;
				mouseDeltaX = controlPoint.mouseX;
				mouseDeltaY = controlPoint.mouseY;
				if(canSizeChange)
				{
					size = new Rectangle(this.x, this.y, this.width, this.height);
					mouseDeltaX = this.parent.mouseX;
				    mouseDeltaY = this.parent.mouseY;
				}
				//trace("deltaY: " + controlPoint.mouseY);
				//op.x += rec.x;		
			}
			//当选择情况下，可能想拖动整个组件
			else
			{
				activeMouseMove();
			}
		}
		
		private function activeMouseMove():void
		{
			mouseDeltaX = this.mouseX;
			mouseDeltaY = this.mouseY;
			controlPoint = null;			
			prepareControl(false);	
		}
		
		protected function control(event: Event):void
		{
			processOperation(false);
		}
		
		private function processOperation(last:Boolean):void
		{
			if(controlPoint)
			{
				if( getStyle("controlType") == "none")
				{
					return;
				}
				
				//改变size:宽度和高度
				if(canSizeChange)
				{
					var size:Rectangle = this.getSize(controlPoint.pos);
					sizeChanged(size, last);
					inResizing = true;
					return;
				}
				//斜切
				var matrix:Matrix = this.getTransForm(controlPoint.pos);
			    if(matrix)
				{
					controlWidgetTransform(matrix);
				}
			}//改变位置
			else if(enableMove)
			{
				 var bounds:Rectangle = new Rectangle(this.x +  mouseX - mouseDeltaX, 
				    this.y +  mouseY - mouseDeltaY,  NaN, NaN);
				 sizeChanged(bounds, last);
			}
		}
		
		private function sizeChanged(bounds:Rectangle, last:Boolean):void
		{
			this.x = bounds.x;
			this.y = bounds.y;
			if(bounds.width)
			{
				this.width = bounds.width;
			}
			if(bounds.height)
			{
				this.height = bounds.height;
			}
			if(!liveSize && !last)
			{
				return;
			}
			if(controlWidget is IBoundsControlAware)
			{
				IBoundsControlAware(controlWidget).boundsControled(bounds);
			}
			else
			{
				controlWidget.x = x;
				controlWidget.y = y;
				controlWidget.width = bounds.width;
				controlWidget.height = bounds.height;
			}
		}
		
		private function getSize(pos: int):Rectangle
		{
		    var tempSize:Rectangle = new Rectangle(size.x, size.y, size.width, size.height);
		    var tempX:Number = this.parent.mouseX;
		    var tempY:Number = this.parent.mouseY;
		    var temp:Number;
		    
		    var deltaX:Number;
		    var deltaY:Number;
		    var controlWidgetMatrix:Matrix = controlWidget.transform.matrix;
		    var min:Number = 3 * this.getStyle("controlRecWidth");
		    
		    //先简后难
		    if(pos == PosConst.MIDDLE_RIGHT)
		    {
		    	temp = tempX - mouseDeltaX;
		    	temp = Math.max(min - tempSize.width , temp);
		    	tempSize.width += temp;
		    }
		    else if(pos == PosConst.LOW_RIGHT)
		    {
		    	deltaX = tempX - mouseDeltaX;
		    	deltaY = tempY - mouseDeltaY;
		    	
		    	
		    	temp = (deltaX - controlWidgetMatrix.c * deltaY) /( 1 - controlWidgetMatrix.b * controlWidgetMatrix.c);
		    	
		    	temp = Math.max(min - tempSize.width , temp);
		    	tempSize.width += temp;
		    	
		    	temp = (deltaY - controlWidgetMatrix.b * deltaX) /( 1 - controlWidgetMatrix.b * controlWidgetMatrix.c);
		    	temp = Math.max(min - tempSize.height , temp);
		    	tempSize.height += temp;
		    }
		    else if(pos == PosConst.LOW_MIDDLE)
		    {
		    	temp = tempY - mouseDeltaY;
		    	temp = Math.max(min - tempSize.height, temp);
		    	tempSize.height += temp;
		    }
		    else if(pos == PosConst.LOW_LEFT)
		    {	   	
		    	deltaX = tempX - mouseDeltaX;
		    	deltaY = tempY - mouseDeltaY;
		    	temp = (deltaX - controlWidgetMatrix.c * deltaY) /( 1 - controlWidgetMatrix.b * controlWidgetMatrix.c);
		    	temp = Math.min(tempSize.width - min, temp);	
		    	
		    	tempSize.x += temp;
		    	tempSize.y += temp * controlWidget.transform.matrix.b;
		    	tempSize.width -= temp;
		    	
                temp = (deltaY - controlWidgetMatrix.b * deltaX) /( 1 - controlWidgetMatrix.b * controlWidgetMatrix.c);               
		    	temp = Math.max(min - tempSize.height, temp);
		    	tempSize.height += temp;
		    }
		    else if(pos == PosConst.MIDDLE_LEFT)
		    {
		    	temp = tempX - mouseDeltaX;
		    	temp = Math.min(tempSize.width - min, temp);
		    	tempSize.x += temp;
		    	tempSize.y += temp * controlWidget.transform.matrix.b;
		    	tempSize.width -= temp;
		    }
		    else if(pos == PosConst.TOP_LEFT)
		    {
				deltaX = tempX - mouseDeltaX;
		    	deltaY = tempY - mouseDeltaY;
		    	var temp2:Number;
		    	temp = (deltaX - controlWidgetMatrix.c * deltaY) /( 1 - controlWidgetMatrix.b * controlWidgetMatrix.c);
		    	temp2 = (deltaY - controlWidgetMatrix.b * deltaX) /( 1 - controlWidgetMatrix.b * controlWidgetMatrix.c);  
		    	//换了一种方式，以前的一直有问题，晕
		    	if((tempSize.width - temp) < min || (tempSize.height - temp2) < min)
		    	{
		    		return  new Rectangle(this.x, this.y, this.width, this.height);
		    	}
		    	tempSize.x += deltaX;
		    	tempSize.y += deltaY;
		    	tempSize.width -= temp;
		    	tempSize.height -= temp2;
		    }
		    else if(pos == PosConst.TOP_MIDDLE)
		    {
		    	temp = tempY - mouseDeltaY;
		    	temp = Math.min(tempSize.height - min, temp);
		    	
		    	tempSize.y += temp;
		    	tempSize.x += temp * controlWidget.transform.matrix.c;
		    	tempSize.height -= temp;
		    }
		    else if(pos == PosConst.TOP_RIGHT)
		    {
		    	deltaX = tempX - mouseDeltaX;
                deltaY = tempY - mouseDeltaY;
                var temp2:Number
                if(1 - controlWidgetMatrix.c * controlWidgetMatrix.b > 0)
                {
                	deltaX = Math.max(min - tempSize.width , deltaX);  
                	temp = (1 - controlWidgetMatrix.c * controlWidgetMatrix.b) * (  tempSize.height - min) + controlWidgetMatrix.b * deltaX;
                	
                	if(controlWidgetMatrix.c  > 0)
                	{
                		temp2 = ( (1 - controlWidgetMatrix.c * controlWidgetMatrix.b) * (tempSize.width - min) +  deltaX) / controlWidgetMatrix.c;
                		deltaY = Math.min(temp, temp2, deltaY);
                	}
                	else
                	{
                		temp2  = controlWidgetMatrix.c == 0 ? 0: ( (1 - controlWidgetMatrix.c * controlWidgetMatrix.b) * (tempSize.width - min) +  deltaX) / controlWidgetMatrix.c;
                		deltaY = Math.max(Math.min(temp, deltaY), temp2);
                	}
                }
                else
                {
                	deltaY = Math.min(tempSize.height - min, deltaY);
                	temp = (1 - controlWidgetMatrix.c * controlWidgetMatrix.b)(min - tempSize.width) + controlWidgetMatrix.c * deltaY;
                	if(controlWidgetMatrix.b > 0)
                	{
                		temp2  = ( deltaY - (1 - controlWidgetMatrix.c * controlWidgetMatrix.b) * (tempSize.height - min)) / controlWidgetMatrix.b;
                		deltaX = Math.min(temp, temp2, deltaX);
                	}
                	else
                	{
                		temp2 = controlWidgetMatrix.b == 0 ? 0 : ( deltaY - (1 - controlWidgetMatrix.c * controlWidgetMatrix.b) * (tempSize.height - min)) / controlWidgetMatrix.b;
                		deltaX = Math.max(Math.min(temp, deltaX), temp2);
                	}
                	
                }
                //deltaY = Math.min(deltaY, tempSize.height - min);
                temp = deltaX;
                //temp = Math.max(min - tempSize.width , temp);   
                tempSize.width += (deltaX - controlWidgetMatrix.c * deltaY) / (1 - controlWidgetMatrix.c * controlWidgetMatrix.b);
                temp  = (deltaY - controlWidgetMatrix.b * deltaX) / (1 - controlWidgetMatrix.c * controlWidgetMatrix.b);
                tempSize.y += temp;
                tempSize.x += temp * controlWidgetMatrix.c;
                 
                //temp = Math.min(tempSize.height - min, temp);
                tempSize.height -= temp;
		    }
		    return tempSize;
		}
		
		public function controlWidgetTransform(matrix:Matrix):void
		{
			 controlWidget.transform.matrix = matrix;
		     this.invalidateSize();
			 this.invalidateDisplayList();
		}
		
		public function getcontrolWidgetTransform():Matrix
		{
			 return controlWidget.transform.matrix;
		}
		
	 	private function getTransForm(pos: int):Matrix
		{
			var p : Point = new Point();
			var a: Number;
			var b: Number;
			var c: Number;
			var d: Number;
			var tx: Number = Number.MIN_VALUE;
			var ty: Number = Number.MIN_VALUE;
			var matrix: Matrix  = controlWidget.transform.matrix;	
			if(!moveDir)
			{
				moveDir = getMoveDirection();
			}
			if(pos == PosConst.MIDDLE_RIGHT || ((pos == PosConst.TOP_RIGHT || 
			    pos == PosConst.LOW_RIGHT) && moveDir == "y"))
			{	
				//trace("befor b: " + matrix.b);	
				p.y = this.mouseY;
				var deltaY:Number = p.y - mouseDeltaY - getInitLocation(pos).y;
				//trace("p.y: " + p.y);	
				//trace("mouseDeltaY: " + mouseDeltaY);	
				//trace("getInitLocation(pos).y: " + getInitLocation(pos).y);	
				//trace("deltaY: " + deltaY);	
				b = deltaY / this.width;
				d = 1;
				a = matrix.a;
				c = matrix.c;
				tempPoint.y = this.y;
				savedB = b;
				//trace("after b: " + b);	
			}
			else if(pos == PosConst.MIDDLE_LEFT || ((pos == PosConst.TOP_LEFT || 
			    pos == PosConst.LOW_LEFT) && moveDir == "y"))
			{
				p.y = this.parent.mouseY;
				var deltaY:Number = p.y - mouseDeltaY - (boxPointOnParent.y + controlPoint.y);
				savedB = savedB != Number.MIN_VALUE ? savedB : matrix.b;
				tempPoint.y = tempPoint.y != Number.MIN_VALUE ? tempPoint.y : this.y;
				b = savedB - (p.y - mouseDeltaY - (tempPoint.y + getInitLocation(pos).y)) / this.width;
				d = 1;
				a = matrix.a;
				c = matrix.c;
				ty = boxPointOnParent.y + deltaY;
			}
			else if(pos == PosConst.TOP_MIDDLE || (moveDir == "x" && (pos == PosConst.TOP_RIGHT ||
			    pos == PosConst.TOP_LEFT )))
			{
				p.x = this.parent.mouseX;
				var deltaX:Number = p.x - mouseDeltaX - (boxPointOnParent.x + controlPoint.x);
				//trace("deltaX: " + deltaX);
				savedC = savedC != Number.MIN_VALUE ? savedC : matrix.c;
				tempPoint.x = tempPoint.x != Number.MIN_VALUE ? tempPoint.x : this.x;
				b = matrix.b;
				d = 1;
				a = 1;
				//c = - (deltaX) / this.height;
				c = savedC - (p.x - mouseDeltaX - tempPoint.x - getInitLocation(pos).x) / this.height;
				tx = boxPointOnParent.x + deltaX;				
			}
			else if(pos == PosConst.LOW_MIDDLE || (moveDir == "x" && (pos == PosConst.LOW_RIGHT ||
			    pos == PosConst.LOW_LEFT )))
			{		
				p.x = this.mouseX;
				var deltaX:Number = p.x - mouseDeltaX - getInitLocation(pos).x;
				b = matrix.b;
				d = 1;
				a = 1;
				c = (deltaX) / this.height;	
				savedC = c;
				tempPoint.x = this.x;
			}		
			this.x = tx != Number.MIN_VALUE? tx : this.x;
			this.y = ty != Number.MIN_VALUE? ty : this.y;
            return new Matrix(a, b, c, d, 0, 0);
		} 
		
		
		/**
		 * 得到将在什么方向上作transform
		 */
		private function getMoveDirection():String
		{
			var angel:Number = Math.atan(controlPoint.mouseY / controlPoint.mouseX);
			if(angel < Math.PI / 4 && angel > - Math.PI / 4 )
			{
				return "x";
			}
			return "y";
		}
		
		
		private function onMouseUp(event: MouseEvent):void
		{
			processOperation(true);
			controlPoint = null;
			moveDir = null;
			inResizing = false;
			//savedB = controlWidget.transform.matrix.b;
			//savedC = controlWidget.transform.matrix.c;	
			prepareControl(true);
		}
		
		/**
		 * 双击的时候，不管该组件是否被选择，如果子组件可编辑，则子组件进入编辑，而该组件选择
		 * 状态置为false;如果组件不可编辑，则选中该组�?
		 */
		private function onClick(event: MouseEvent):void
		{
			var target:Object = event.target;
			if(controlWidget is IEidtableComponent && !IEidtableComponent(controlWidget).isInEdit())
			{
				IEidtableComponent(controlWidget).startEdit();
				this.selected = false;
				this.showControl = true;
			}
			else if( !(controlWidget is IEidtableComponent))
			{
				this.selected = true;
			}
		}
		
		
		/**
		 * 为这次的控制作准备（当added为false, 比如填加监听器），或者已经准备完毕（当added为true, 删去监听器）
		 */
		private function prepareControl(added: Boolean):void
		{
			if(added)
			{
				this.removeEventListener(Event.ENTER_FRAME, control);
			    this.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouse);
			}
			else
			{
				this.addEventListener(Event.ENTER_FRAME, control);
		    	this.stage.addEventListener(MouseEvent.MOUSE_UP, onMouse);
			}
		}
		
		private function getLoacionOnParent(event: Event):void
		{
		    this.removeEventListener(Event.ADDED_TO_STAGE, getLoacionOnParent);
	        boxPointOnParent.x = this.x;
	        boxPointOnParent.y = this.y;
	        this.invalidateDisplayList();
		}
		
		private function setControlPointsVisible(value: Boolean):void
		{
			 if(tlPoint)
			 { 	
			 	 tlPoint.visible = value;
			 	 tmPoint.visible = value;
			 	 trPoint.visible = value;
			 	 mlPoint.visible = value;
			 	 mrPoint.visible = value;
			 	 llPoint.visible = value;
			 	 lmPoint.visible = value;
			 	 lrPoint.visible = value;
			 }	 
		}
		
		private function operationEnd(event: MouseEvent):void
		{
			var target:DisplayObject = event.target as DisplayObject;
			if(!isAncestor(target, this) && target != this)
			{
				this.started = false;
				if(this.stage)
				{
					this.stage.removeEventListener(MouseEvent.MOUSE_DOWN, operationEnd);
				}				
			}
		}
		
		public  function isAncestor(child:DisplayObject, com:DisplayObjectContainer):Boolean
		{
			var parent:DisplayObjectContainer = child.parent;
			while(parent)
			{
				if(parent == com)
				{
					return true;
				}
				parent = parent.parent;
			}
			return false;
		}
		
		public function set moveEnable(value:Boolean):void
		{
			enableMove = value;
		}
		
		public function get controlWidget():DisplayObject
		{
			return _controlWidget;
		}

        /**
        * 设置需要控制的组件
        * 一般这些组件需要被控制，那么他们的容器一定是basiclayout，所以我们
        * 就自动把controlBox按照被控制组件的位置加上去
        */
		public function set controlWidget(v:DisplayObject):void
		{
			_controlWidget = v;
			if(v.parent)
			{
				var rec:Rectangle = v.getBounds(v.parent);
				this.x = rec.x;
				this.y = rec.y;
				this.setActualSize(rec.width, rec.height);
				v.parent.addChild(this);
				this.started = true;
				this.showControl = true;
				this.selected = true;
				activeMouseMove();
				this.invalidateDisplayList();
			}
		}
		
		/**
		 * 释放内存，删掉一些没必要的引�?
		 */
		public function clear():void
		{
			this.removeEventListener(MouseEvent.MOUSE_DOWN, onMouse);
			this.removeEventListener(MouseEvent.DOUBLE_CLICK, onMouse);
			if(this.hasEventListener(Event.ENTER_FRAME))
			{
				this.removeEventListener(Event.ENTER_FRAME, control);
			}
			if(this.stage && stage.hasEventListener(MouseEvent.MOUSE_UP))
			{		
			    this.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouse);
			}
			while(this.numChildren)
			{
				this.removeChildAt(0);
			}
			if(this.parent)
			{
				this.parent.removeChild(this);
			}
			_controlWidget = null;
			tlPoint = null;
			tmPoint = null;
			trPoint = null;
		 	mlPoint = null;
		    mrPoint = null;
		 	llPoint = null;
		 	lmPoint = null;
		 	lrPoint = null;
		}

		public function get liveSize():Boolean
		{
			return _liveSize;
		}

		public function set liveSize(v:Boolean):void
		{
			_liveSize = v;
		}

		public function get unit():Number
		{
			return _unit;
		}

		public function set unit(v:Number):void
		{
			_unit = v;
		}

		public function get inResizing():Boolean
		{
			return _inResizing;
		}

		public function set inResizing(v:Boolean):void
		{
			_inResizing = v;
			displayTextField.visible = v;
		}

		
	}
}